(function (zn){

    var __slice = Array.prototype.slice;
    var __global = zn.GLOBAL,
        __document = __global.document,
        __tempDom = __document.createElement('div'),
        __tempStyle = __tempDom.style;

    var rsizeElement = /width|height|top|right|bottom|left|size|margin|padding/i,
        rHasUnit = /[c-x%]/,
        PX = 'px',
        rUpperCameCase = /(?:^|-)([a-z])/g,
        rDeCameCase = /([A-Z])/g,
        cssNumber = {
            'lineHeight': true,
            'zIndex': true,
            'zoom': true
        },
        styleHooks = {
            float: 'cssFloat'
        };

    var StyleUtil = {
        getCssText: function (styles) {
            var _cssText = [''];
            zn.each(styles, function (styleValue,styleName) {
                _cssText.push(this.getStyleProperty(styleName, true) + ':' + this.getStyleValue(styleName, styleValue));
            }, this);

            return _cssText.join(';');
        },
        getStyleValue: function (inName, inValue) {
            var _property = this.getStyleProperty(inName),
                _value = inValue;

            if (rsizeElement.test(_property)) {
                if (!rHasUnit.test(inValue) && !cssNumber[_property]) {
                    _value += PX;
                }
            }

            return _value;
        },
        getStyleProperty: function (inName, isLowerCase) {
            var _property = this.lowerCamelCase(inName);

            if (_property in __tempStyle) {
                if (isLowerCase) {
                    _property = this.deCamelCase(inName);
                }
            } else {
                if (isLowerCase) {
                    //_property = env.prefix()[1] + inName;
                    _property = inName;
                } else {
                    //_property = env.prefix()[0] + this.upperCamelCase(inName);
                    _property = this.upperCamelCase(inName);
                }
            }

            return styleHooks[inName] || _property;
        },
        lowerCamelCase: function (inName) {
            var _camelizeString = this.upperCamelCase(inName);
            return _camelizeString.charAt(0).toLowerCase() + _camelizeString.substring(1);
        },
        upperCamelCase: function (inName) {
            return inName.replace(rUpperCameCase,function (match,group1) {
                return group1.toUpperCase();
            });
        },
        deCamelCase: function (inName) {
            return inName.replace(rDeCameCase,function (match,group1) {
                return '-' + group1.toLowerCase();
            });
        },
        capitalize: function (inString) {
            return inString.charAt(0).toUpperCase() + inString.slice(1);
        }
    }

    /**
     * @class DOM
     * @namespace zn.ui.dom
     * @desc The element for dom.
     */
    zn.class('zn.ui.dom.DOM', zn.ui.core.Element, {
        partial: true,
        properties: {

        },
        methods: {
            getClass: function (){
                return this._dom.className;
            },
            setClass: function (className){
                return this._dom.className = className, this;
            },
            addClass: function (){
                var _classList = this._dom.classList;
                return _classList.add.apply(_classList, __slice.call(arguments)), this;
            },
            removeClass: function (){
                var _classList = this._dom.classList;
                return _classList.remove.apply(_classList, __slice.call(arguments)), this;
            },
            hasClass: function (className){
                return this._dom.classList.contains(className);
            },
            toggleClass: function (className){
                return this._dom.classList.toggle(className), this;
            },
            setStyle: function (key, value) {
                var _property = StyleUtil.getStyleProperty(key);
                this._dom.style[property] = StyleUtil.getStyleValue(key, value);
            },
            getStyle: function (key, isInline) {
                var _dom = this._dom,
                    _property = StyleUtil.getStyleProperty(key),
                    _styles = isInline ? _dom.style : __global.getComputedStyle(_dom, null);

                return _styles[_property] || '';
            },
            removeStyle: function (key) {
                var _property = StyleUtil.getStyleProperty(key, true);
                return this._dom.style.removeProperty(_property), this;
            },
            hasStyle: function (key) {
                return this._dom.style.cssText.indexOf(key + ':') > -1;
            },
            setStyles: function (styles) {
                var _styles = zn.is(styles, 'string') ? styles: StyleUtil.getCssText(styles);
                return this._dom.style.cssText += _styles, this;
            },
            getComputedStyle: function (key) {
                return __global.getComputedStyle(this._dom, null).getPropertyValue(key);
            }
        }
    });

})(zn);
